#!/usr/bin/env python
# encoding: utf-8
"""
cusum.py

Created by Dmitry Tsybin on 2011-03-09.
Copyright (c) 2011. All rights reserved.
"""

import sys
import os
import unittest
from constants import *

class Cusum:
	'''Класс для использования метода кумулятивных сумм.'''
	
	def __init__(self):
		self.meanValue = 0
		self.counter = 0
		self.penalty = 0
		self.discordThreshold = 0
		self.crashThreshold = 0
		self.result = 0
	
	def calculate(self, nowValue):
		self.meanValue = (nowValue + self.meanValue * self.counter) / (self.counter + 1)
		self.penalty = max(0, nowValue - self.meanValue + self.penalty)
		self.counter += 1
		return self.penalty
		
	def discord(self, nowValue, discordThreshold = 0.1, crashThreshold = 0.5):
		'''функция возвращает STATUS'''
		
		self.discordThreshold = discordThreshold
		self.crashThreshold= crashThreshold
			
		self.calculate(nowValue)
		
		if self.penalty < self.discordThreshold:
			self.result = STATUS.ok
		elif self.penalty < self.crashThreshold:
			self.result = STATUS.discord
		else:
			self.result = STATUS.crash
	
		return self.result
		

class CusumTest(unittest.TestCase):
	knownValuesDiscord = [ ([0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09], STATUS.discord),
	 					([1, 2, 3, 4, 5, 6, 7, 8, 9], STATUS.crash),
						([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 1, 1, 0.1], STATUS.crash),
						([ 0 ], STATUS.ok)]
					
	knownValuesCalculate = [ ([0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09], 0.17999999999999997),
							([1, 2, 3, 4, 5, 6, 7, 8, 9], 18.0),
							([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 1, 1, 0.1], 1.3963636363636365),
							([ 0 ], 0.0)]							
	
	def testCalculate1(self):
		for listVals, status in self.knownValuesCalculate:
			testUnit = Cusum()
			for nowVal in listVals:
				result = testUnit.calculate(nowVal)
			self.assertEqual(status, result)
			
	"""Почему-то тест не работает на пустом списке"""		
	def testDiscord1(self):
		for listVals, status in self.knownValuesDiscord:
			testUnit = Cusum()
			for nowVal in listVals:
				result = testUnit.discord(nowVal)
			self.assertEqual(status, result)
		

if __name__ == '__main__':
	unittest.main()	